package jaux.tank.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.entity.ContentType;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class HttpRequestUtils {

	static ObjectMapper objectMapper = new ObjectMapper();
	
	/**
	 * 请求指定地址返回的JSON
	 * 
	 * @param url
	 * @return
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static <T> T getJSON(String url, Map<String, String> params, TypeReference<T> valueTypeRef) throws ClientProtocolException, IOException {
		return objectMapper.readValue(getContent(url,params,null), valueTypeRef);
	}

	/**
	 * 请求指定地址返回的JSON
	 * 
	 * @param url
	 * @return
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static <T> T getJSON(String url, TypeReference<T> valueTypeRef) throws ClientProtocolException, IOException {
		return objectMapper.readValue(getContent(url), valueTypeRef);
	}

	/**
	 * 请求指定地址返回的JSON
	 * 
	 * @param url
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static <T> T getJSON(String url, Map<String, String> params,TypeReference<T> valueTypeRef, Map<String, String> header)
			throws ClientProtocolException, IOException {
		return objectMapper.readValue(getContent(url, params, header), valueTypeRef);
	}
	/**
	 * 请求指定地址返回的JSON
	 * 
	 * @param url
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static <T> T getJSON(String url, TypeReference<T> valueTypeRef, Map<String, String> header)
			throws ClientProtocolException, IOException {
		return objectMapper.readValue(getContent(url, header), valueTypeRef);
	}

	/**
	 * 请求指定地址的内容
	 * 
	 * @param url
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String getContent(String url) throws ClientProtocolException, IOException {
		return Request.Get(url).setCacheControl("no-cache").execute().returnContent().asString(StandardCharsets.UTF_8);

	}

	/**
	 * 请求指定地址的内容
	 * 
	 * @param url
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String getContent(String url, Map<String, String> header)
			throws ClientProtocolException, IOException {

		final Request getRequest = Request.Get(url);
		getRequest.setCacheControl("no-cache");
		if (header != null) {
			for (String key : header.keySet()) {
				getRequest.setHeader(key, header.get(key));
			}
		}
		return getRequest.execute().returnContent().asString(Charset.forName("utf-8"));

	}

	/**
	 * 请求指定地址的内容
	 * 
	 * @param url
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String getContent(String url, Map<String, String> params, Map<String, String> header)
			throws ClientProtocolException, IOException {
		String requestUrl = null;
		if (params != null && params.size() > 0) {
			String urlParams = params.entrySet().stream().map(fp -> {
				String kv = fp.getKey()+"=";
				if(StringUtils.isNotBlank(fp.getValue())) {
					try {
					kv+=URLEncoder.encode(fp.getValue(), "UTF-8");
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
				}
				return kv;
			}).collect(Collectors.joining("&"));
			requestUrl = url + (url.contains("?") ? "&" : "?")  + urlParams;

		} else {
			requestUrl = url;
		}
		final Request getRequest = Request.Get(requestUrl);
		getRequest.setCacheControl("no-cache");
		if (header != null) {
			for (String key : header.keySet()) {
				getRequest.setHeader(key, header.get(key));
			}
		}
		final Response response = getRequest.execute();
		return response.returnContent().asString(Charset.forName("utf-8"));

	}

	/**
	 * 发送post请求内容.
	 *
	 * @param url the url
	 * @param body the body
	 * @param header the header
	 * @return the string
	 * @throws ClientProtocolException the client protocol exception
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public static String postContent(String url, Object body, Map<String, String> header)
			throws ClientProtocolException, IOException {
		final Request postRequest = Request.Post(url);
		postRequest.setCacheControl("no-cache");
		if (header != null) {
			for (String key : header.keySet()) {
				postRequest.setHeader(key, header.get(key));
			}
		}
		return postRequest.bodyString(objectMapper.writeValueAsString(body),ContentType.APPLICATION_JSON).execute().returnContent().asString(Charset.forName("utf-8"));
	}
	/**
	 * 发送post请求内容
	 * 
	 * @param url
	 * @param names
	 * @param values
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String postContent(String url, String[] names, String[] values, Map<String, String> header)
			throws ClientProtocolException, IOException {
		Form form = Form.form();
		for (int i = 0; i < names.length; i++) {
			form.add(names[i], values[i]);
		}
		final Request postRequest = Request.Post(url);
		postRequest.setCacheControl("no-cache");
		if (header != null) {
			for (String key : header.keySet()) {
				postRequest.setHeader(key, header.get(key));
			}
		}
		return postRequest.bodyForm(form.build()).execute().returnContent().asString(Charset.forName("utf-8"));
	}
	/**
	 * 发送put请求内容.
	 *
	 * @param url the url
	 * @param body the body
	 * @param header the header
	 * @return the string
	 * @throws ClientProtocolException the client protocol exception
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public static String putContent(String url, Object body, Map<String, String> header)
			throws ClientProtocolException, IOException {
		final Request putRequest = Request.Put(url);
		putRequest.setCacheControl("no-cache");
		if (header != null) {
			for (String key : header.keySet()) {
				putRequest.setHeader(key, header.get(key));
			}
		}
		return putRequest.bodyString(objectMapper.writeValueAsString(body),ContentType.APPLICATION_JSON).execute().returnContent().asString(Charset.forName("utf-8"));
	}
}
